//
//@author jltxseo
// Created by junlintianxia on 2016/4/21.
//
#include <jni.h>
#include <android/log.h>
#include "cn_jltx_ndkcallback_javajni_DataProvider.h"
#include "cn_jltx_ndkcallback_javajni_DataProviderCall.h"

#define LOG_TAG "ndk.out.c"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)


JNIEXPORT void JNICALL Java_cn_jltx_ndkcallback_javajni_DataProvider_callmethod1(JNIEnv *env, jobject obj)
{
    //在c代码里面调用java代码里面的方法
    // java 反射
    //1 . 找到java代码的 class文件
    //    jclass      (*FindClass)(JNIEnv*, const char*);
    jclass dpclazz = (*env)->FindClass(env, "cn/jltx/ndkcallback/javajni/DataProvider");
    if(dpclazz == 0){
        LOGI("find class error");
    }
    LOGI("find class ");

    //2 寻找class里面的方法
    //   jmethodID   (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
    jmethodID method1 = (*env)->GetMethodID(env,dpclazz,"helloFromJava","()V");
    if(method1==0){
        LOGI("find method1 error");
        return;
    }
    LOGI("find method1 ");
    //3 .调用这个方法
    //    void        (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
    (*env)->CallVoidMethod(env,obj,method1);
}


JNIEXPORT void JNICALL Java_cn_jltx_ndkcallback_javajni_DataProvider_callmethod2(JNIEnv *env, jobject obj)
{
    // java 反射
    //1 . 找到java代码的 class文件
    //    jclass      (*FindClass)(JNIEnv*, const char*);
    jclass dpclazz = (*env)->FindClass(env, "cn/jltx/ndkcallback/javajni/DataProvider");
    if(dpclazz == 0){
        LOGI("find class error");
    }
    LOGI("find class ");

    //2 寻找class里面的方法
    //   jmethodID   (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
    jmethodID method2 = (*env)->GetMethodID(env,dpclazz,"Add","(II)I");
    if(method2==0){
        LOGI("find method2 error");
        return;
    }
    LOGI("find method2 ");
    //3 .调用这个方法
    //    void        (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...);
    int result =  (*env)->CallIntMethod(env,obj,method2,4,5);
    LOGI("c method2 result = %d",result);
}

JNIEXPORT void JNICALL Java_cn_jltx_ndkcallback_javajni_DataProvider_callmethod3
(JNIEnv *env, jobject obj)
{
    //1 . 找到java代码的 class文件
    //    jclass      (*FindClass)(JNIEnv*, const char*);
    jclass dpclazz = (*env)->FindClass(env, "cn/jltx/ndkcallback/javajni/DataProvider");
    if(dpclazz==0){
    LOGI("find class error");
    return;
    }
    LOGI("find class ");

    //2 寻找class里面的方法
    //   jmethodID   (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
    jmethodID method3 = (*env)->GetMethodID(env,dpclazz,"printString","(Ljava/lang/String;)V");
    if(method3==0){
        LOGI("find method3 error");
        return;
    }
    LOGI("find method3 ");

    //3 .调用这个方法
    //    void        (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
    (*env)->CallVoidMethod(env,obj,method3,(*env)->NewStringUTF(env,"haha in c"));
}

JNIEXPORT void JNICALL Java_cn_jltx_ndkcallback_javajni_DataProvider_callmethod4
(JNIEnv *env, jobject obj)
{
    //1 . 找到java代码的 class文件
    //    jclass      (*FindClass)(JNIEnv*, const char*);
    jclass dpclazz = (*env)->FindClass(env, "cn/jltx/ndkcallback/javajni/DataProvider");
    if(dpclazz==0){
        LOGI("find class error");
        return;
    }
    LOGI("find class ");

    //2 寻找class里面的方法
    //非静态方法用该函数获取方法id jmethodID   (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
    //静态方法应该改成(*GetStaticMethodID)(JNIEnv*, jclass, const char*, const char*);这个方法来获取静态方法的id
    jmethodID method4 = (*env)->GetStaticMethodID(env,dpclazz,"printStaticStr","(Ljava/lang/String;)V");
    if(method4==0){
    LOGI("find method4 error");
    return;
    }
    LOGI("find method4 ");

    //调用一个静态的java方法    void        (*CallStaticVoidMethod)(JNIEnv*, jclass, jmethodID, ...);
    (*env)->CallStaticVoidMethod(env,dpclazz,method4,(*env)->NewStringUTF(env,"static api call in c"));
}

/**
 * native调用代码和java代码在不同的类里面
 */
JNIEXPORT void JNICALL Java_cn_jltx_ndkcallback_javajni_DataProviderCall_callDataProviderMethod1
(JNIEnv *env, jclass cls)
{
    //1 . 找到java代码的 class文件
    //    jclass      (*FindClass)(JNIEnv*, const char*);
    jclass dpclazz = (*env)->FindClass(env, "cn/jltx/ndkcallback/javajni/DataProvider");
    if(dpclazz==0){
        LOGI("find class error");
        return;
    }
    LOGI("find class ");

    //2 寻找class里面的方法
    //   jmethodID   (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
    jmethodID method1 = (*env)->GetMethodID(env,dpclazz,"helloFromJava","()V");
    if(method1==0){
        LOGI("find method1 error");
        return;
    }

    LOGI("find method1 ");


    //3.因为没有DataProvider这个类的对应对象obj所以这里要先实例化一个对象才可以调用
    //AllocObject(jclass clazz)
    jobject obj = (*env)->AllocObject(env,dpclazz);

    //4 .调用这个方法
    //    void        (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
    (*env)->CallVoidMethod(env,obj,method1);
}